package com.orangelife.service.propFeeReductionInfo.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.github.pagehelper.PageHelper;
import com.orangelife.common.MybaitsGenericDaoSubLogic;
import com.orangelife.exception.AppBizException;
import com.orangelife.service.offset.IOffsetService;
import com.orangelife.service.propFeeAccount.IPropFeeAccountService;
import com.orangelife.service.propFeeAccount.model.AmountHandleDto;
import com.orangelife.service.propFeeAccount.model.PropFeeAccountDto;
import com.orangelife.service.propFeeReductionDetail.IPropFeeReductionDetailService;
import com.orangelife.service.propFeeReductionDetail.model.PropFeeReductionDetailDto;
import com.orangelife.service.propFeeReductionInfo.IPropFeeReductionInfoService;
import com.orangelife.service.propFeeReductionInfo.model.PropFeeReductionInfoDto;
import com.orangelife.setting.constant.CodeConst;
import com.orangelife.setting.constant.InfoConst;
import com.orangelife.setting.constant.TypeConst;
import com.orangelife.utils.IdUtil;
import com.orangelife.utils.StringUtils;
import com.orangelife.webservice.service.propFeeReductionInfo.entity.ReductionInfoDto;

/*****************************************************************
 * Copyright(C) ORANGELIFE Corporation CodeConst.BIS_CODE_68001015. All Rights
 * Reserved.
 *****************************************************************/
/*
 * ============================================================== 功能名
 * PropFeeReductionInfo类的 service层的增删改查
 * 
 * @author @author zhr
 * 
 * @version 1.1.0
 * 
 * @date 2016-11-24 14:19:57
 * ==============================================================
 */
@Service("propFeeReductionInfoService")
public class PropFeeReductionInfoServiceImpl extends MybaitsGenericDaoSubLogic
		implements IPropFeeReductionInfoService {
	private static Logger logger = Logger
			.getLogger(PropFeeReductionInfoServiceImpl.class);

	public static Logger getLogger() {
		return logger;
	}

	public static void setLogger(Logger logger) {
		PropFeeReductionInfoServiceImpl.logger = logger;
	}

	@Resource(name = "propFeeReductionDetailService")
	private IPropFeeReductionDetailService propFeeReductionDetailService;
	@Resource(name = "propFeeAccountService")
	private IPropFeeAccountService propFeeAccountService;
	@Resource(name = "offsetService")
	private IOffsetService offsetService;

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int addPropFeeReductionInfo(
			PropFeeReductionInfoDto propFeeReductionInfo)
			throws AppBizException {

		Assert.notNull(propFeeReductionInfo);
		/************************************************
		 * 判断输入参数的长度以及是否能为空
		 ************************************************/

		if (!StringUtils.isBlank(propFeeReductionInfo.getApprovalCode())) {
			if (propFeeReductionInfo.getApprovalCode().length() > 256) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "审批编号长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getReductionReason())) {
			if (propFeeReductionInfo.getReductionReason().length() > 2048) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "折减原因长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getCreateuser())) {
			if (propFeeReductionInfo.getCreateuser().length() > 32) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "创建者长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getStatus())) {
			if (propFeeReductionInfo.getStatus().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002,
						"状态(1未生效，2已生效，3已撤回)长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getEffectType())) {
			if (propFeeReductionInfo.getEffectType().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "长度超出");
			}
		}
		if (propFeeReductionInfo.getReductionID() == null) {
			propFeeReductionInfo.setReductionID(IdUtil.getuuId());
		}

		propFeeReductionInfo.setItemStat(TypeConst.FLAG_ON);
		propFeeReductionInfo.setTscreate(new Date());
		propFeeReductionInfo.setTsedit(new Date());
		return this.getSqlSession().insert(
				"PropFeeReductionInfoMapper.insertSelective",
				propFeeReductionInfo);
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int editPropFeeReductionInfo(
			PropFeeReductionInfoDto propFeeReductionInfo)
			throws AppBizException {

		Assert.notNull(propFeeReductionInfo);
		/************************************************
		 * 判断输入参数的长度以及是否能为空
		 ************************************************/
		if (StringUtils.isBlank(propFeeReductionInfo.getReductionID())) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}
		PropFeeReductionInfoDto oldPropFeeReductionInfo = this
				.findPropFeeReductionInfoByID(propFeeReductionInfo
						.getReductionID());

		if (!StringUtils.isBlank(propFeeReductionInfo.getApprovalCode())) {
			if (propFeeReductionInfo.getApprovalCode().length() > 256) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "审批编号长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getReductionReason())) {
			if (propFeeReductionInfo.getReductionReason().length() > 2048) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "折减原因长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getCreateuser())) {
			if (propFeeReductionInfo.getCreateuser().length() > 32) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "创建者长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getStatus())) {
			if (propFeeReductionInfo.getStatus().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002,
						"状态(1未生效，2已生效，3已撤回)长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeReductionInfo.getEffectType())) {
			if (propFeeReductionInfo.getEffectType().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "长度超出");
			}
		}

		if (oldPropFeeReductionInfo == null) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}
		propFeeReductionInfo.setTsedit(new Date());
		return this.getSqlSession().update(
				"PropFeeReductionInfoMapper.updateByPrimaryKeySelective",
				propFeeReductionInfo);
	}

	@Override
	public PropFeeReductionInfoDto findPropFeeReductionInfoByID(
			String propFeeReductionInfoID) throws AppBizException {
		if (StringUtils.isBlank(propFeeReductionInfoID)) {

			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}

		/************************************************
		 * 判断实体是否存在
		 ************************************************/
		PropFeeReductionInfoDto oldPropFeeReductionInfo = this.getSqlSession()
				.selectOne(
						"PropFeeReductionInfoSearchMapper.selectByPrimaryKey",
						propFeeReductionInfoID);
		if (oldPropFeeReductionInfo == null) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}

		if (TypeConst.FLAG_OFF.equals(oldPropFeeReductionInfo.getItemStat())) {

			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}
		return oldPropFeeReductionInfo;
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int deletePropFeeReductionInfoByLogic(String propFeeReductionInfoID)
			throws AppBizException {

		if (StringUtils.isBlank(propFeeReductionInfoID)) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}
		/************************************************
		 * 判断实体是否存在
		 ************************************************/
		PropFeeReductionInfoDto oldPropFeeReductionInfo = this
				.findPropFeeReductionInfoByID(propFeeReductionInfoID);

		oldPropFeeReductionInfo.setItemStat(TypeConst.FLAG_OFF);
		oldPropFeeReductionInfo.setTsedit(new Date());
		return this.getSqlSession().update(
				"PropFeeReductionInfoMapper.updateByPrimaryKeySelective",
				oldPropFeeReductionInfo);
	}

	@Override
	public List<Map<String, Object>> findPropFeeReductionInfoByPage(
			String commID, String searchType, String startTime, String endTime,
			String status, String tsCreate, String search, int pageNo,
			int pageSize) throws AppBizException {

		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		if (!StringUtils.isBlank(startTime)) {
			map.put("startTime", Long.parseLong(startTime) / 1000);
		}
		if (!StringUtils.isBlank(endTime)) {
			map.put("endTime", Long.parseLong(endTime) / 1000);
		}
		if (!StringUtils.isBlank(status)) {
			map.put("status", status);
		}
		map.put("commID", commID);
		if (!StringUtils.isBlank(searchType)) {
			map.put("searchType", String.valueOf(searchType));
		}
		map.put("tsCreate", tsCreate);
		map.put("search", search);
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeReductionInfoSearchMapper.findAllPropFeeReductionInfo",
				map);
		return list;
	}

	@Override
	public List<PropFeeReductionInfoDto> getPropFeeReductionInfoByPage(
			String tsCreate, String search, int pageNo, int pageSize)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("tsCreate", tsCreate);
		map.put("search", search);
		PageHelper.startPage(pageNo, pageSize);
		List<PropFeeReductionInfoDto> list = this
				.getSqlSession()
				.selectList(
						"PropFeeReductionInfoSearchMapper.getAllPropFeeReductionInfoDto",
						map);
		return list;
	}

	@Override
	public List<Map<String, Object>> selectPropFeeReductionInfoByRelevantID(
			String reductionID, String commID, String apartmentID, String status)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("reductionID", reductionID);
		map.put("commID", commID);
		map.put("apartmentID", apartmentID);
		map.put("status", status);

		List<Map<String, Object>> list = this
				.getSqlSession()
				.selectList(
						"PropFeeReductionInfoSearchMapper.selectPropFeeReductionInfoDtoyRelevantID",
						map);
		return list;
	}

	@Override
	public List<PropFeeReductionInfoDto> findPropFeeReductionInfoByRelevantID(
			String reductionID, String commID, String apartmentID, String status)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("reductionID", reductionID);
		map.put("commID", commID);
		map.put("apartmentID", apartmentID);
		map.put("status", status);

		List<PropFeeReductionInfoDto> list = this
				.getSqlSession()
				.selectList(
						"PropFeeReductionInfoSearchMapper.findPropFeeReductionInfoDtoByRelevantID",
						map);
		return list;
	}

	@Override
	public List<PropFeeReductionInfoDto> bauthfindPropFeeReductionInfo(
			List<String> propFeeReductionInfoIDs) throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		List<PropFeeReductionInfoDto> list = this
				.getSqlSession()
				.selectList(
						"PropFeeReductionInfoSearchMapper.batchFindPropFeeReductionInfo",
						propFeeReductionInfoIDs);
		return list;
	}

	@Override
	public List<Map<String, Object>> bauthfindPropFeeReductionInfoByMap(
			Map<String, Object> propFeeReductionInfo) throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		List<Map<String, Object>> list = this
				.getSqlSession()
				.selectList(
						"PropFeeReductionInfoSearchMapper.batchFindPropFeeReductionInfoByMap",
						propFeeReductionInfo);
		return list;
	}

	@Override
	public void clearCache() throws AppBizException {
		System.out.println("清除缓存成功");
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int addPropFeeReductionInfoAndDetail(
			ReductionInfoDto reductionInfoDto) throws AppBizException {

		PropFeeReductionInfoDto p = new PropFeeReductionInfoDto();
		p.setCommID(reductionInfoDto.getCommID());
		p.setApartmentID(reductionInfoDto.getApartmentID());
		// p.setEffectTime(effectTime);
		p.setReductionID(IdUtil.getuuId());
		p.setReductionMoney(reductionInfoDto.getReductionMoney());
		p.setReductionReason(reductionInfoDto.getReductionReason());
		p.setApprovalCode(reductionInfoDto.getApprovalCode());
		p.setStatus("1");
		p.setEffectTime(reductionInfoDto.getEffectTime());
		p.setEffectType(reductionInfoDto.getEffectType());
		p.setCreateuser(reductionInfoDto.getCreateuser());
		p.setCreateuserID(reductionInfoDto.getCreateuserID());

		String startDate = null;
		String endDate = null;
		BigDecimal total = BigDecimal.ZERO;

		for (PropFeeReductionDetailDto pd : reductionInfoDto
				.getReductionDetail()) {
			pd.setReductionID(p.getReductionID());
			pd.setCreateuserID(reductionInfoDto.getCreateuserID());
			propFeeReductionDetailService.addPropFeeReductionDetail(pd);
			total = total.add(pd.getReductionMoney());
			if (startDate == null) {

				startDate = pd.getStartDate();
			} else {
				if (pd.getStartDate().compareTo(startDate) < 0) {

					startDate = pd.getStartDate();
				}

			}
			if (endDate == null) {

				endDate = pd.getEndDate();
			} else {
				if (pd.getEndDate().compareTo(endDate) > 0) {

					endDate = pd.getEndDate();
				}
			}

		}

		if (startDate.equals(endDate)) {

			p.setReductionPeriod(startDate);
		} else {

			p.setReductionPeriod(startDate + "-" + endDate);
		}
		if (p.getReductionMoney().compareTo(total) != 0) {

			throw new AppBizException(CodeConst.SYS_CODE_4001, "细项金额 和总扣减金额不匹配");
		}

		this.addPropFeeReductionInfo(p);

		return 1;
	}

	@Override
	public List<Map<String, Object>> getReductionInfo(
			Map<String, Object> param, int pageIndex, int pageSize)
			throws AppBizException {

		PageHelper.startPage(pageIndex, pageSize);
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeReductionInfoSearchMapper.getPropFeeReductionInfoList",
				param);
		return list;

	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public void autoReduction() throws AppBizException {
		String reductionID = null;
		String reductionMoney = null;
		String commID = null;
		String apartmentID = null;
		PropFeeReductionInfoDto prf = new PropFeeReductionInfoDto();

		Map<String, Object> apartmentInfo = new HashMap<String, Object>();
		// 获取已生效的折减信息
		while (true) {

			List<Map<String, Object>> list = this.getEffectReductionInfo(null,
					null, 1, 1000);

			if (list == null || list.size() == 0) {
				break;
			} else {
				for (Map<String, Object> map : list) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					reductionID = map.get("reduction_id").toString();
					reductionMoney = map.get("reduction_money").toString();
					commID = map.get("comm_id").toString();
					apartmentID = map.get("apartment_id").toString();
					prf.setReductionID(reductionID);
					prf.setStatus("2");

					// 获取房屋账户余额
					PropFeeAccountDto propFeeAccount = propFeeAccountService
							.getAccountByApartID(apartmentID);
					if (propFeeAccount == null) {

						return;
					}

					this.editPropFeeReductionInfo(prf);
					// 加钱

					/**
					 * /**
					 * 
					 * 结算方式（'0现金',1 '刷卡',2 '银行转账', 3"橙子生活代缴",4
					 * "支付宝缴费",5,折减优惠,6押金转存，7预存冲抵）*
					 ** 
					 * private String statementType;
					 * 
					 * /**
					 * 
					 * 1"支付宝",2 "积分",3 "余额支付", 4"连连支付", 5"微信支付",6 "服务窗口支付宝",
					 * 8物业费钱包*
					 ** 
					 * private String statementChannel;
					 */
					AmountHandleDto a = new AmountHandleDto();
					a.setAccountID(propFeeAccount.getAccountID());
					a.setMoney(new BigDecimal(reductionMoney));
					a.setRemark("预存物业费(折减优惠)");
					a.setApartmentID(propFeeAccount.getApartmentID());
					a.setLinkID(reductionID);
					a.setTotalMoney(propFeeAccount.getMoney());
					a.setOperation("1");
					a.setStatementType("5");
					a.setLogType(9);
					a.setItem("预存物业费");
					propFeeAccountService.handleAccount(a);
					if (apartmentInfo.get(apartmentID) == null) {
						Map<String, Object> m = new HashMap<String, Object>();
						m.put("commID", commID);
						m.put("userID", prf.getCreateuserID());
						m.put("apartmentID", apartmentID);
						apartmentInfo.put(apartmentID, m);
					}

				}

			}

		}

		/***
		 * 触发抵扣信息
		 */
		for (Entry<String, Object> entry : apartmentInfo.entrySet()) {

			try {
				@SuppressWarnings("unchecked")
				Map<String, Object> houseInfo = (Map<String, Object>) apartmentInfo
						.get(entry.getKey());
				offsetService.autoOffset(
						houseInfo.get("commID").toString(),
						houseInfo.get("apartmentID").toString(),
						houseInfo.get("userID") != null ? houseInfo.get(
								"userID").toString() : null, null);
			} catch (Exception e) {
				logger.error(e.getMessage());
			}

		}

	}

	@Override
	public List<Map<String, Object>> getEffectReductionInfo(String commID,
			String apartmentID, int pageNo, int pageSize)
			throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeReductionInfoSearchMapper.getEffectReductionInfo",
				param);
		return list;
	}

	@Override
	public List<Map<String, Object>> synchpReductionData(Map<String, Object> map)
			throws AppBizException {

		/************************************************
		 * 设置输入参数
		 ************************************************/
		if (map.containsKey("tsedit")) {
			if (map.get("tsedit") != null) {
				if (!StringUtils.isInt(map.get("tsedit").toString())) {
					throw new AppBizException(2, "参数类型错误");
				}
				map.put("tsedit",
						Long.parseLong(map.get("tsedit").toString()) / 1000);
			}
		}
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeReductionInfoSearchMapper.synchpReductionData", map);
		return list;
	}

}